<template>
<div>
  {{myName}}
</div>
  <button @click="handleClick" ref="buttonRef">按钮</button>
  {{comref}}
  {{ count }}
  <div v-for="(item, key) in objss" :key="key">{{ item }}-{{ key }}</div>
</template>

<script setup>
import {
  ref,
  computed,
  watch,
  reactive,
  watchEffect,
  onMounted,
  effect,
  watchPostEffect,
  nextTick,
  version,
  watchSyncEffect,
  readonly,
  unref
} from "vue";

const valRef = ref(1);

let myName = ref('Nancy');
const reactiveObj = reactive({ sss: "wuey" });
const newSet = new Set([reactiveObj, 2, 3]);
const proxySet = reactive(newSet);
const jshd=unref(reactiveObj)
console.log(jshd,45630000);

//proxySet.clear(reactiveObj)

const count = ref(0);
const qwee = reactive([11]);
const zxcd = reactive({ age: 20 });
const objss = reactive({
  name: "js",
  age: 20,
  [Symbol("ss")]: "ok",
  lists: [1, 12, , 3],
  flag: false,
});
// const qas = {}
// const presy=reactive([qas])
// console.log(presy.includes(presy[0]), 2000);

// effect(() => {
//   console.log(qwee.includes(1),900);
// })
// setTimeout(() => {
//   
//  qwee.push(100)
// },2000)
effect(() => {
  //Object.keys(qwee)
  Reflect.ownKeys(qwee)
  // for (let key in qwee) {
  //   let val = qwee[key];
  // }
});

// Reflect.ownKeys(objss)
// console.log(Object.keys(objss));
watchEffect(() => {
  qwee.push(11);
  console.log(123566);
});

// setTimeout(() => {
//   objss.name = "yuis";
// }, 2000);
// const lists = ref([1]);
const lists = reactive({ value: [123] });
const handleClick = (e) => {
  console.log(e);
  count.value++;
};
watchEffect(() => {
  console.log(111);
});
const stop = watchEffect((onInvalidate) => {
  onInvalidate(() => {
    console.log(5555);
  });
  if (count.value > 3) {
    console.log(count.value, "963");
    stop();
  }
});
watch(
  () => JSON.parse(JSON.stringify(lists.value)),
  (v1, v2) => {
    console.log(v1, v2, "6333");
  }
);
watch(
  lists.value,
  (v1, v2) => {
    console.log(v1, v2, "99999999");
  },
  { deep: true }
);
watch(lists.value, (v1, v2) => {
  console.log(v1, v2, "1000");
});
setTimeout(() => {
  // lists.value.push(11);
  lists.value.push(200);
});
const buttonRef=ref(null)



nextTick(()=>{
  console.log("nextTick");
})
onMounted(() => {
  console.log("onMounted");
});
const comref=computed(()=>{
  console.log(version,"computed");
  return buttonRef.value
})

watchEffect(()=>{
   console.log(buttonRef.value,"pre");
})
watchSyncEffect(()=>{
   console.log(buttonRef.value,"watchSyncEffect");//watchSyncEffect是同步执行基本不用
})
watchPostEffect(()=>{
  console.log(buttonRef.value,"watchPostEffect");
})
//flush是pre(默认可以不写)和Sync，谁在前面谁先执行


//(重要)执行先后顺序，属性flush:'pre'的watchEffect和带有{ immediate: true }的watch谁写在前面谁先执行>computed>onMounted
//(重要)带有{ immediate: true }的watch>computed>带有flush: "post"的watchEffect>onMounted
//watch和watchEffect,computed的详细区别 请看https://www.jianshu.com/p/c257aad46344或https://blog.csdn.net/m0_51969330/article/details/123673334


// vue3中响应式的注意事项(非常重要,面试加分项)
//1.数组和对象响应式的注意事项
// 1.1(for key in obj),Object.keys(obj),Reflect.ownKeys(obj)会触发源码中ownKeys函数做track依赖收集(obj是对象的话会收集key为Symbol("iterate")的依赖，obj是数组的话会收集key为length的依赖)
// 1.2 上面例子中push方法的时候实际上是通过arrays[2]=100执行trigger(key="2")函数通过判断获取length的依赖并执行，而不是直接执行key='length'的依赖(因为这个时候length的新值和老值一样所以不执行trigger)
// 1.3 上面例子中pop方法则是通过触发trigger(key='length')执行依赖的
const arrays=reactive([1,2])
effect(() => {
  console.log(arrays.length, 2000);
});
arrays.push(100)
arrays.pop()
//2.(Set, Map, WeakSet, WeakMap)响应式的注意事项
//keys, values, entries,forEach方法和size属性都是收集key为Symbol("iterate")的依赖，
//(add，set，delete，clear)方法触发key为Symbol("iterate")的依赖
const we={}
const newMap = new Map([[we, "xiaohua"]]);
const proxynewMap = reactive(newMap);

// effect(() => {
//   console.log(proxynewMap.size,proxynewMap, 1000);
// });
// proxynewMap.set(we, "huahua");//effect会执行因为源码在trigger函数set时候做处理，执行了key为Symbol("iterate")的依赖
effect(() => {
  console.log(proxynewMap.we,proxynewMap, 11111111111000);
});
proxynewMap.set(we, "huahua");



const cousssnt = ref(1)
const obj = reactive({})

obj.cousssnt = cousssnt

console.log(obj.cousssnt) // 1
console.log(obj.cousssnt === cousssnt.value)
    
cousssnt.value++
console.log(cousssnt.value) // 2
console.log(obj.cousssnt) // 2

obj.cousssnt++
console.log(obj.cousssnt) // 3
console.log(cousssnt.value) // 3



const original = reactive({ count: 0 })
const dgff=ref(10)
const copy = readonly(original)
const copy12 = readonly(dgff)
watchEffect(() => {
  // 用来做响应性追踪
  // console.log(copy.count,63789000000)
  console.log(copy12.value,63789000000)
})

// 更改源属性会触发其依赖的侦听器
setTimeout(()=>{
  // original.count=900
  dgff.value=200
},2000)

</script>

<style scoped>
.done {
  color: gray;
  text-decoration: line-through;
}
</style>
